import pytest
from typing import Dict

# 模拟API响应
class MockAPI:
    def __init__(self):
        self.error_map = {
            "InvalidInstanceId.Malformed": lambda p: p["InstanceId"] == "ins-123",
            "InvalidImageId.NotFound": lambda p: p.get("ImageId") == "img-not-found",
            "InvalidParameter.ParameterConflict": lambda p: "Password" in p.get("LoginSettings", {}) and "KeyIds" in p.get("LoginSettings", {}),
            "UnauthorizedOperation.InvalidToken": lambda p: p.get("Token") == "invalid-token",
            "UnsupportedOperation.InstanceStateShutdown": lambda p: p.get("InstanceState") == "SHUTDOWN",
            "ResourceInUse": lambda p: p.get("ResourceStatus") == "IN_USE",
            "InternalServerError": lambda p: p.get("IsMockError", False),
            "InvalidAccount.InsufficientBalance": lambda p: p.get("AccountBalance", 100) < 100,
            "MissingParameter": lambda p: "InstanceId" not in p,
            "InvalidParameterValue.InvalidImageFormat": lambda p: p.get("ImageFormat") == "RAW",
            "ResourceNotFound.KeyPairNotFound": lambda p: p.get("KeyIds") == ["key-not-found"],
            "InvalidParameterValue.IllegalHostName": lambda p: p.get("HostName") == "invalid_hostname",
            "UnsupportedOperation.InstanceChargeType": lambda p: p.get("InstanceChargeType") == "prepaid",
            "UnauthorizedOperation.MFANotFound": lambda p: p.get("NeedMFA", False) and not p.get("MFAToken"),
            "ResourceInsufficient.CloudDiskSoldOut": lambda p: p.get("SystemDisk", {}).get("DiskSize", 0) > 500
        }

    def reset_instance(self, params: Dict) -> Dict:
        for code, checker in self.error_map.items():
            if checker(params):
                return {"Error": {"code": code}}
        # 成功场景（确保必填参数存在）
        if all(param in params for param in ["Action", "Version", "Region", "InstanceId"]):
            return {"Response": {"RequestId": "mock-id"}}
        return {"Error": {"code": "MissingParameter"}}

# 初始化模拟对象
mock_api = MockAPI()

# 参数化测试用例（覆盖所有错误码）
@pytest.mark.parametrize("test_case", [
    {"name": "InvalidInstanceId.Malformed", "params": {"InstanceId": "ins-123", "Action": "a", "Version": "v", "Region": "r"}},
    {"name": "InvalidImageId.NotFound", "params": {"InstanceId": "i", "ImageId": "img-not-found", "Action": "a", "Version": "v", "Region": "r"}},
    {"name": "InvalidParameter.ParameterConflict", "params": {"InstanceId": "i", "LoginSettings": {"Password": "p", "KeyIds": ["k"]}, "Action": "a", "Version": "v", "Region": "r"}},
    {"name": "UnauthorizedOperation.InvalidToken", "params": {"InstanceId": "i", "Token": "invalid-token", "Action": "a", "Version": "v", "Region": "r"}},
    {"name": "UnsupportedOperation.InstanceStateShutdown", "params": {"InstanceId": "i", "InstanceState": "SHUTDOWN", "Action": "a", "Version": "v", "Region": "r"}},
    {"name": "ResourceInUse", "params": {"InstanceId": "i", "ResourceStatus": "IN_USE", "Action": "a", "Version": "v", "Region": "r"}},
    {"name": "InternalServerError", "params": {"InstanceId": "i", "IsMockError": True, "Action": "a", "Version": "v", "Region": "r"}},
    {"name": "InvalidAccount.InsufficientBalance", "params": {"InstanceId": "i", "AccountBalance": 50, "Action": "a", "Version": "v", "Region": "r"}},
    {"name": "MissingParameter", "params": {"Action": "a", "Version": "v", "Region": "r"}},
    {"name": "InvalidParameterValue.InvalidImageFormat", "params": {"InstanceId": "i", "ImageFormat": "RAW", "Action": "a", "Version": "v", "Region": "r"}},
    {"name": "ResourceNotFound.KeyPairNotFound", "params": {"InstanceId": "i", "KeyIds": ["key-not-found"], "Action": "a", "Version": "v", "Region": "r"}},
    {"name": "InvalidParameterValue.IllegalHostName", "params": {"InstanceId": "i", "HostName": "invalid_hostname", "Action": "a", "Version": "v", "Region": "r"}},
    {"name": "UnsupportedOperation.InstanceChargeType", "params": {"InstanceId": "i", "InstanceChargeType": "prepaid", "Action": "a", "Version": "v", "Region": "r"}},
    {"name": "UnauthorizedOperation.MFANotFound", "params": {"InstanceId": "i", "NeedMFA": True, "Action": "a", "Version": "v", "Region": "r"}},
    {"name": "ResourceInsufficient.CloudDiskSoldOut", "params": {"InstanceId": "i", "SystemDisk": {"DiskSize": 1024}, "Action": "a", "Version": "v", "Region": "r"}},
])
def test_error_codes(test_case):
    response = mock_api.reset_instance(test_case["params"])
    assert "Error" in response, f"预期错误响应，实际成功: {test_case['name']}"
    assert response["Error"]["code"] == test_case["name"], f"错误码不匹配: {test_case['name']}"

# 成功场景测试
def test_success_case():
    params = {
        "InstanceId": "ins-valid",
        "Action": "ResetInstance",
        "Version": "2017-03-12",
        "Region": "ap-guangzhou"
    }
    response = mock_api.reset_instance(params)
    assert "Response" in response, "成功响应缺失"
    assert "RequestId" in response["Response"], "RequestId缺失"